package com.jushu.storbox;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.util.Log;
import com.jushu.storbox.constant.ClientConfig;
import com.jushu.storbox.constant.ConfigurableConstants;
import com.jushu.storbox.constant.SystemConfig;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.database.IUserDao;
import com.jushu.storbox.entities.DownloadObject;
import com.jushu.storbox.entities.UploadObject;
import com.jushu.storbox.entities.User;
import com.jushu.storbox.handler.CrashHandler;
import com.jushu.storbox.manager.AlbumUploadTaskManager;
import com.jushu.storbox.manager.CatchManager;
import com.jushu.storbox.manager.DownloadTaskManager;
import com.jushu.storbox.manager.ShareDownloadTaskManager;
import com.jushu.storbox.manager.UploadTaskManager;
import com.jushu.storbox.network.WifiController;
import com.jushu.storbox.service.ICloudDriveService;
import com.jushu.storbox.task.tqueue.DownloadTask;
import com.jushu.storbox.util.PublicTools;
import com.jushu.storbox.view.resolve.UploadResolver;
import com.huawei.sharedrive.sdk.android.exception.ClientException;
import com.huawei.sharedrive.sdk.android.model.response.FolderListResponse;
import com.huawei.sharedrive.sdk.android.modelV2.response.RefreshToken;
import com.huawei.sharedrive.sdk.android.modelV2.response.ServerUrlV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.UserResponseV2;
import com.huawei.sharedrive.sdk.android.serviceV2.CommonClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.UserClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.UserClientV2.ServerRequestParamter;
import com.huawei.sharedrive.sdk.android.serviceV2.UserClientV2.SystemType;
import com.huawei.sharedrive.sdk.android.util.StringUtil;

import static android.R.id.list;

//import com.huawei.sharedrive.service.ShareDriveService;

/**
 * 
 * cloud drive application data
 * 
 */
public class ShareDriveApplication extends Application {

	protected static final String TAG = ShareDriveApplication.class.getSimpleName();

	/** cloud drive authorization */
	private String authorization = null;

	/** cloud drive ShareDriveApplication instance */
	private static ShareDriveApplication instance;

	/** cloud drive wnerID */
	private String wnerID = null;

	/** cloud drive uam_address */
	private String app_address = null;
	
	/** cloud drive uam_address */
	private String uam_address = null;
	
	/** cloud drive ufm_address */
	private String ufm_address = null;

	/** cloud drive folderListResponse */
	private FolderListResponse folderListResponse;

	/** my cloud drive page position */
	private int myCloudDrivePage = 0;

	/** my cloud drive page position */
	private int mySharePage = 0;

	private String shareOwnerName = "";

	/** scrollView is scrolling */
	private boolean isScrolling = false;
	
	private int notificationID = ClientConfig.NOTIFICATION_ID;
	
    private static long lastClickTime;
    
    private boolean isCanMove = false;
        
    private boolean animShowing = false;
    
    UserClientV2 userClient = null;
    
    private User currentUser = null;
    
    private WifiController wifiController = new WifiController(ShareDriveApplication.this);
    
    ServerRequestParamter defaultRequestParamter = new ServerRequestParamter() {

		@Override
		public String getLoginName() {
			return PublicTools.getLoginUserName(ShareDriveApplication.this);
		}

		@Override
		public String getLoginPassword() {
			return PublicTools.getLoginUserPassFail(ShareDriveApplication.this);
		}  
		
		@Override
		public String getRuntimeAuthorization() {
			return getAuthorization();
		}

		@Override
		public String getServerAddress(SystemType system) {
			String serverAddress = "";
			switch(system) {
				case CLOUDAPP:
					serverAddress = ShareDriveApplication.this.getServerAddress();
					break;
					
				case UAM:
					serverAddress = ShareDriveApplication.this.getUamAddress();
					break;
					
				case UFM:
					serverAddress = ShareDriveApplication.this.getUfmAddress();
					break;
			}
			return serverAddress;
		}

		@Override
		public void onLoginSuccess(UserResponseV2 response) {
			PublicTools.setRefreshToken(ShareDriveApplication.this, response.getRefreshToken());
			PublicTools.setExpiredAt(ShareDriveApplication.this, response.getTimeout());
			ShareDriveApplication.this.setWnerID(response.getCloudUserId());
			ShareDriveApplication.this.setAuthorization(response.getToken());
			
//			PublicTools.setClientUserName(ShareDriveApplication.this, response.getLoginName());
			
			SharedPreferences setting = getSharedPreferences(ClientConfig.settings, Context.MODE_PRIVATE);
			Editor eidt = setting.edit();
			eidt.putBoolean(ClientConfig.LOGIN_STATE, true);
			eidt.commit();
			
			String encryPass = PublicTools.getEncryptorLoginPassFail(ShareDriveApplication.this);
			if(response.getCloudUserId() != null) {
				IUserDao userDao = DAOFactory.instance(ShareDriveApplication.this).getUserDao();
				User localUser = userDao.getUser(response.getCloudUserId());
				if(localUser == null) {
//					String userName = response.getLoginName();

					String userName = PublicTools.getLoginUserName(ShareDriveApplication.this);
					String defaultUserStorePath = ClientConfig.CACHE_DEFAULT_PATH 
							+ ClientConfig.CACHE_CONTEXT + userName ;
					localUser = new User();
					localUser.setLongName(userName);
					localUser.setEncryPassword(encryPass);
					localUser.setUserId(response.getCloudUserId());
					localUser.setStorePath(defaultUserStorePath);
					userDao.insertUser(localUser);
				} else {
					localUser.setEncryPassword(encryPass);
					userDao.updatePassword(localUser);
				}
				setCurrentUser(localUser);
			}
		}

		@Override
		public void onRequestServerSuccess(ServerUrlV2 response, SystemType system) {
			String serverAddress = response.getServerUrl();
			switch(system) {
			case CLOUDAPP:
				if(!StringUtil.isBlank(serverAddress)) {
					ShareDriveApplication.this.setServerAddress(serverAddress);
					CommonClientV2.getInstanceV2().setServiceURL(serverAddress);
				}
				break;
				
			case UAM:
				if(!StringUtil.isBlank(serverAddress)) {
					ShareDriveApplication.this.setUamAddress(serverAddress);
					CommonClientV2.getInstanceV2().setUAMURL(serverAddress);
				}
				break;
				
			case UFM:
				if(!StringUtil.isBlank(serverAddress)) {
					ShareDriveApplication.this.setUfmAddress(serverAddress);
					CommonClientV2.getInstanceV2().setUFMURL(serverAddress);
				}
				break;
			}
		}

		@Override
		public void onFaildRequest(Throwable e) {
			Log.e(TAG,"Use default request: operation failed!");
		}

		@Override
		public void onRefreshSuccess(RefreshToken refreshResponse) {
			ShareDriveApplication.this.setAuthorization(refreshResponse.getToken());
			PublicTools.setRefreshToken(ShareDriveApplication.this, refreshResponse.getRefreshToken());
			PublicTools.setExpiredAt(ShareDriveApplication.this, refreshResponse.getTimeout());
		}

		@Override
		public void onLogoutSuccess(String httpStatus) {
			SharedPreferences setting = getSharedPreferences(ClientConfig.settings, Context.MODE_PRIVATE);
			Editor eidt = setting.edit();
			eidt.putBoolean(ClientConfig.LOGIN_STATE, false);
			eidt.commit();
			
			CommonClientV2.getInstanceV2().setServiceURL("");
			CommonClientV2.getInstanceV2().setUFMURL("");
			CommonClientV2.getInstanceV2().setUAMURL("");
//			ShareDriveApplication.this.setServerAddress("");
			ShareDriveApplication.this.setUfmAddress("");
			ShareDriveApplication.this.setUamAddress("");
			ShareDriveApplication.this.setWnerID("");
			ShareDriveApplication.this.setAuthorization("");
			PublicTools.setClientUserPassFail(ShareDriveApplication.this, "");
			PublicTools.setClientUserName(ShareDriveApplication.this, "");
			PublicTools.setRefreshToken(ShareDriveApplication.this, "");
			PublicTools.setExpiredAt(ShareDriveApplication.this, 0L);
		}

		@Override
		public void BadServerAddress(SystemType system) {
			String serverAddress = "";
			switch(system) {
				case CLOUDAPP:
					serverAddress = ShareDriveApplication.this.getServerAddress();
					CommonClientV2.getInstanceV2().setServiceURL(serverAddress);
					break;
					
				case UAM:
					serverAddress = ShareDriveApplication.this.getUamAddress();
					CommonClientV2.getInstanceV2().setUAMURL(serverAddress);
					break;
					
				case UFM:
					serverAddress = ShareDriveApplication.this.getUfmAddress();
					CommonClientV2.getInstanceV2().setUFMURL(serverAddress);
					break;
			}
		}
		
	};
    
	public boolean isAnimShowing() {
		return animShowing;
	}

	public void setAnimIsShowing(boolean animShowing) {
		this.animShowing = animShowing;
	}
    
	public boolean isCanMove() {
		return isCanMove;
	}

	public void setCanMove(boolean isCanMove) {
		this.isCanMove = isCanMove;
	}

	public int getNotificationID() {
		if ((ClientConfig.NOTIFICATION_ID * 2) <= notificationID) {
			notificationID = ClientConfig.NOTIFICATION_ID;
        } else {
        	notificationID++;
        }
		return notificationID;
	}

	public void setNotificationID(int notificationID) {
		this.notificationID = notificationID;
	}

	public boolean isScrolling() {
		return isScrolling;
	}

	public void setScrolling(boolean isScrolling) {
		this.isScrolling = isScrolling;
	}

	public boolean updateDialogFlag = false;
	
	private String fileEncPath = "";

	//cloud bitmaps recycle
	private List<SoftReference<Bitmap>> cloudBitmaps = new ArrayList<SoftReference<Bitmap>>();
	//shared bitmaps recycle
	private List<SoftReference<Bitmap>> sharedBitmaps = new ArrayList<SoftReference<Bitmap>>();
	//shared bitmaps recycle
	private List<SoftReference<Bitmap>> tempBitmaps = new ArrayList<SoftReference<Bitmap>>();

	/**
	 * ShareDriveApplication get ShareDriveApplication instance
	 * 
	 * @return ShareDriveApplication get ShareDriveApplication instance
	 */
	public static ShareDriveApplication getInstance() {
		return instance;
	}

	/** shareDriveService */
	private ICloudDriveService shareDriveService;

	public ICloudDriveService getShareDriveService() {
		return shareDriveService;
	}

	public void setShareDriveService(ICloudDriveService shareDriveService) {
		this.shareDriveService = shareDriveService;
	}

	/** ScrollView is refreshing in MycloudDrive */
	private boolean isRefreshing = false;

	public boolean isRefreshing() {
		return isRefreshing;
	}

	public void setRefreshing(boolean isRefreshing) {
		this.isRefreshing = isRefreshing;
	}

	public UserClientV2 getUserClientV2() {
		if(userClient == null) {
			userClient = UserClientV2.getInstance();
		}
		if(userClient != null) {
			userClient.setServerRequestParamter(defaultRequestParamter);
		}
		return userClient;
	}
	
	/**
	 * ShareDriveApplication onCreate
	 */
	@Override
	public void onCreate() {

		super.onCreate();
		instance = this;
		CrashHandler crashHandler = CrashHandler.getInstance();
		crashHandler.init(getApplicationContext());
		AlbumUploadTaskManager.instance().startScheduler();
		CatchManager.getInstance().initCatch(instance);
		
		ConfigurableConstants.init(instance);
		SystemConfig.init(instance);

		loadDownloadTask();
		loadUploadTask();

        ShareDownloadTaskManager.start();
        
		if(userClient == null) {
			userClient = UserClientV2.getInstance();
		}
		
		if(userClient != null) {
			userClient.setServerRequestParamter(defaultRequestParamter);
		}
	}

	/**
	 * 继续下载上次中断任务
	 */
	private void loadDownloadTask() {
		//增加代码
		List<DownloadObject> dbDownloadList =  DAOFactory.instance(getApplicationContext()).getDownloadFileDao().getDownloadFileList();
		for(DownloadObject downloadItem : dbDownloadList) {
			DownloadTaskManager.startTask(getApplicationContext(), downloadItem);
		}
		DownloadTaskManager.start();
		UploadTaskManager.start();
	}

	/**
	 * 继续上传上次中断任务
	 */
	private void loadUploadTask() {
		/**	此前应该取出上传列表，并放入上传队列*/
		//从数据库取出上传列表
		List<UploadObject> UploadList =  DAOFactory.instance(getApplicationContext()).getUploadFileDao().getUploadFileList();
		//放入任务队列里面
		for(UploadObject uploadItem : UploadList) {
			UploadTaskManager.startTask(getApplicationContext(), uploadItem);
		}
	}


	/**
	 * ShareDriveApplication get cloud drive authorization
	 * 
	 * @return String get cloud drive authorization
	 */
	public String getAuthorization() {
		if(StringUtil.isBlank(authorization)) {
			authorization = PublicTools.getAuthorization(this);
		}
		return authorization;
	}

	/**
	 * ShareDriveApplication set cloud drive authorization
	 * 
	 * @param authorization
	 *            String set cloud drive authorization
	 */
	public void setAuthorization(String authorization) {
		PublicTools.setAuthorization(this, authorization);
		if(StringUtil.isBlank(authorization)){
			PublicTools.setExpiredAt(this, 0L);
		}
		this.authorization = null;
	}

	public String getServerAddress() {
		if(StringUtil.isBlank(app_address)) {
			app_address = PublicTools.getServerAddress(this);
		}
		return app_address;
	}
	
	public void setServerAddress(String serverAddress) {
		PublicTools.setServerAddress(this, serverAddress);
		app_address = serverAddress;
	}
	
	public String getUamAddress() {
		if(StringUtil.isBlank(uam_address)) {
			uam_address = PublicTools.getUAMAddress(this);
		}
		return uam_address;
	}
	
	public void setUamAddress(String uamAddress) {
		PublicTools.setUAMADDRESS(this, uamAddress);
		uam_address = uamAddress;
	}
	
	public String getUfmAddress() {
		if(StringUtil.isBlank(ufm_address)) {
			ufm_address = PublicTools.getUFMAddress(this);
		}
		return ufm_address;
	}
	
	public void setUfmAddress(String ufmAddress) {
		PublicTools.setUFMADDRESS(this, ufmAddress);
		ufm_address = ufmAddress;
	}
	
	/**
	 * ShareDriveApplication get cloud drive wnerID
	 * 
	 * @return String get cloud drive wnerID
	 */
	public String getWnerID() {
		if(StringUtil.isBlank(wnerID)) {
			wnerID = PublicTools.getOwnerId(this);
		}
		return wnerID;
	}

	/**
	 * ShareDriveApplication set cloud drive wnerID
	 */
	public void setWnerID(String wnerID) {
		PublicTools.setOwnerId(this, wnerID);
		this.wnerID = wnerID;
	}

	/**
	 * ShareDriveApplication get cloud drive FolderListResponse
	 * 
	 * @return String get cloud drive FolderListResponse
	 */
	public FolderListResponse getFolderListResponse() {
		return folderListResponse;
	}

	/**
	 * ShareDriveApplication set cloud drive FolderListResponse
	 * 
	 * @param folderListResponse
	 *            FolderListResponse set cloud drive FolderListResponse
	 */
	public void setFolderListResponse(FolderListResponse folderListResponse) {
		this.folderListResponse = folderListResponse;
	}

	/**
	 * @return the myCloudDrivePage
	 */
	public int getMyCloudDrivePage() {
		return myCloudDrivePage;
	}

	/**
	 * @param myCloudDrivePage
	 *            the myCloudDrivePage to set
	 */
	public void setMyCloudDrivePage(int myCloudDrivePage) {
		this.myCloudDrivePage = myCloudDrivePage;
	}

	/**
	 * @return the mySharePage
	 */
	public int getMySharePage() {
		return mySharePage;
	}
	
	/**
	 * @return isFastDoubleClick
	 */
	public boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        if ( 0 < timeD && timeD < 600) {   
            return true;   
        }   
        lastClickTime = time;   
        return false;   
    }

	/**
	 * @param mySharePage
	 *            the mySharePage to set
	 */
	public void setMySharePage(int mySharePage) {
		this.mySharePage = mySharePage;
	}

	public String getShareOwnerName() {
		return shareOwnerName;
	}

	public void setShareOwnerName(String shareOwnerName) {
		this.shareOwnerName = shareOwnerName;
	}
	
	public String getFileEncPath() {
		return fileEncPath;
	}

	public void setFileEncPath(String fileEncPath) {
		this.fileEncPath = fileEncPath;
	}

	public List<SoftReference<Bitmap>> getCloudBitmaps() {
		return cloudBitmaps;
	}

	public void addCloudBitmaps(Bitmap cloudBitmap) {
		if (null != cloudBitmaps || null != cloudBitmap) {
			cloudBitmaps.add(new SoftReference<Bitmap>(cloudBitmap));
		}
	}

	public void clearCloudBitmaps() {
		if (null != cloudBitmaps) {
			cloudBitmaps.clear();
		}
	}

	public void removeCloudBitmaps(Bitmap cloudBitmap) {
		if (null != cloudBitmaps || null != cloudBitmap) {
			cloudBitmaps.remove(new SoftReference<Bitmap>(cloudBitmap));
		}
	}

	//
	public List<SoftReference<Bitmap>> getSharedBitmaps() {
		return sharedBitmaps;
	}

	public void addSharedBitmaps(Bitmap sharedBitmap) {
		if (null != sharedBitmaps || null != sharedBitmap) {
			sharedBitmaps.add(new SoftReference<Bitmap>(sharedBitmap));
		}
	}

	public void clearSharedBitmaps() {
		if (null != sharedBitmaps) {
			sharedBitmaps.clear();
		}
	}

	public void removeSharedBitmaps(Bitmap sharedBitmap) {
		if (null != sharedBitmaps || null != sharedBitmap) {
			sharedBitmaps.remove(new SoftReference<Bitmap>(sharedBitmap));
		}
	}
	
	//
	public List<SoftReference<Bitmap>> getTempBitmaps() {
		return tempBitmaps;
	}

	public void addTempBitmaps(Bitmap tempBitmap) {
		if (null != tempBitmaps || null != tempBitmap) {
			tempBitmaps.add(new SoftReference<Bitmap>(tempBitmap));
		}
	}

	public void clearTempBitmaps() {
		if (null != tempBitmaps) {
			tempBitmaps.clear();
		}
	}

	public void removeTempBitmaps(Bitmap tempBitmap) {
		if (null != tempBitmaps || null != tempBitmap) {
			tempBitmaps.remove(new SoftReference<Bitmap>(tempBitmap));
		}
	}

	private Intent ShareNotFinishIntent = null;
	
	public Intent getShareNotFinishIntent() {
		return ShareNotFinishIntent;
	}

	public void setShareNotFinishIntent(Intent intent) {
		ShareNotFinishIntent = intent;
	}
	
	public void smartAuthorization() throws ClientException {
		if(PublicTools.isAuthiorzationGotoTimeout(this)){
			PublicTools.reGetTokenByLoginInBanck(this);
		}
	}

	public WifiController getWifiController() {
		return wifiController;
	}

	public void setWifiController(WifiController wifiController) {
		this.wifiController = wifiController;
	}

	//new struct
	public User getCurrentUser() {
		if(currentUser == null && StringUtil.isNotBlank(wnerID)) {
			currentUser = DAOFactory.instance(this).getUserDao().getUser(wnerID);
		}
		return currentUser;
	}
	
	public void setCurrentUser(User user) {
		currentUser = user;
	}
	
}
